package yxy.game.pm2.bean;

import org.redisson.api.RAtomicLong;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.game.pm2.bean.currency.CurrencyGroup;
import yxy.game.pm2.bean.currency.CurrencyNotEnoughException;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.db.newDao.PointDAO;
import yxy.game.pm2.bean.db.po.PointPo;
import yxy.game.pm2.bean.module.BaseGameRedisLockBean;

import java.util.ArrayList;
import java.util.List;

/** 积分资源 */
public class Point extends BaseGameRedisLockBean {

	// redis==========================================================================

	static public String key(String playerCode, CurrencyType type) {
		return String.format("PLAYER:%s:POINT:%d", playerCode, type.getNumber());
	}

	static private RAtomicLong touch(String key) throws RedisException {
		return RedisManager.client(redis()).getAtomicLong(key);
	}

	static public long get(String playerCode, CurrencyType type, Boolean isNewPlayer) {
		try {
			String key = key(playerCode, type);
			RAtomicLong bucket = touch(key);
			//是新用户就不去数据库查
			if(!bucket.isExists() && !isNewPlayer){
				Long point = MySQLCacheDAO.getV(key, Long.class);

				if(point != null){
					bucket.set(point.longValue());
				}
			}

			//初始化为0
			if(!bucket.isExists()){
				bucket.set(0);
			}

			return bucket.get();
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	static public void add(String playerCode, CurrencyType type, long number) throws RedisException {
		String lockKey = lockKey(playerCode, type);
		try {
			if (tryLock(lockKey)) {
				String key = key(playerCode, type);
				RAtomicLong bucket = touch(key);
				bucket.addAndGet(number);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			unlock(lockKey);
		}
	}

	static public void minus(String playerCode, CurrencyType type, long number) throws CurrencyNotEnoughException {
		String lockKey = lockKey(playerCode, type);
		try {
			if (tryLock(lockKey)) {
				String key = key(playerCode, type);
				RAtomicLong bucket = touch(key);
				long value = bucket.get();
				if (number > value) {
					throw new CurrencyNotEnoughException(type, 0);
				}
				value = bucket.addAndGet(-number);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new CurrencyNotEnoughException(type, 0);
		} finally {
			unlock(lockKey);
		}
	}

	static private String lockKey(String playerCode, CurrencyType type) {
		return String.format("lock:%s", key(playerCode, type));
	}

	//数据归档到数据库
	public static void saveToDB(String playerCode) {
		try {
			//存储
			List<PointPo> pointPoList = new ArrayList<>();

			ArrayList<CurrencyType> cts = CurrencyType.getCurrencyTypeByGroup(CurrencyGroup.POINT);
			for(CurrencyType ct:cts){
				String key = key(playerCode, ct);
				if (touch(key).isExists()) {
					Long value = touch(key).get();
					MySQLCacheDAO.setV(key, value.longValue());
				}
			}
			//PointDAO.replace(pointPoList);
		} catch (Exception e){
			e.printStackTrace();
		}
	}

	//从redis移走数据
	public static void removeAllFromRedis(String playerCode) {
		try {
			//一次性全部清除所有的
			ArrayList<CurrencyType> cts = CurrencyType.getCurrencyTypeByGroup(CurrencyGroup.POINT);
			for(CurrencyType ct:cts) {
				touchBucket(key(playerCode,ct)).delete();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void set(String playerCode,CurrencyType type,Long num) {
		try {
			String key = key(playerCode, type);
			RAtomicLong touch = touch(key);
			touch.set(num);
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}


}
